#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

#include "bind.h"
#include "isp.h"
#include "mipi.h"
#include "sys.h"
#include "vi.h"
#include "vo.h"
#include "vpss.h"
#include "isp.h"
#include "ive.h"
#include "uart.h"
#include "nnie.h"

#include "hi_type.h"
#include "mpi_vpss.h"
#include "mpi_vo.h"
#include "hi_ive.h"

volatile HI_BOOL g_bWorking = HI_TRUE;

HI_VOID SignalHandler(HI_S32 SigNum)
{
    g_bWorking = HI_FALSE;
}

HI_S32 main(HI_S32 argc, HI_CHAR *argv[])
{
    HI_S32 s32Ret;

    signal(SIGINT, SignalHandler);
    signal(SIGQUIT, SignalHandler);

    VI_DEV ViDev = 0;
    VI_PIPE ViPipe = 0;
    VI_CHN ViChn = 0;

    combo_dev_t MipiDev = ViDev;

    VPSS_GRP VpssGrp = 0;
    VPSS_CHN VpssChn = 1;

    VO_DEV VoDev = 0;
    VO_LAYER VoLayer = VoDev;
    VO_CHN VoChn = 0;

    s32Ret = SYS_Init();
    if (HI_SUCCESS != s32Ret)
    {
        printf("SYS Init failed!\n");
        goto EXIT1;
    }

    s32Ret = SNS_MIPI_Init(MipiDev);
    if (HI_SUCCESS != s32Ret)
    {
        printf("SNS_MIPI_Init failed!\n");
        goto EXIT2;
    }

    s32Ret = VI_Init(ViDev, ViPipe, ViChn);
    if (HI_SUCCESS != s32Ret)
    {
        printf("VI_Init failed!\n");
        goto EXIT3;
    }

    s32Ret = ISP_Init(ViPipe);
    if (HI_SUCCESS != s32Ret)
    {
        printf("ISP_Init failed!\n");
        goto EXIT4;
    }

    s32Ret = VPSS_Init(VpssGrp, VpssChn);
    if (HI_SUCCESS != s32Ret)
    {
        printf("VPSS_Init failed!\n");
        goto EXIT5;
    }

    s32Ret = VI_Bind_VPSS(ViPipe, ViChn, VpssGrp, VpssChn);
    if (HI_SUCCESS != s32Ret)
    {
        printf("VI_BIND_VPSS failed!\n");
        goto EXIT6;
    }

    s32Ret = LCD_MIPI_Init();
    if (HI_SUCCESS != s32Ret)
    {
        printf("LCD_MIPI_Init failed!\n");
        goto EXIT7;
    }

    s32Ret = VO_Init(VoDev, VoLayer, VoChn);
    if (HI_SUCCESS != s32Ret)
    {
        printf("VO_Init failed!\n");
        goto EXIT8;
    }

    // SVP_NNIE_PARAM_S stNnieParam = {0};
    // stNnieParam.u32MaxInputNum = 1;
    // stNnieParam.u32MaxRoiNum = 0;

    // s32Ret = SVP_NNIE_Init("", &stNnieParam);
    // if (HI_SUCCESS != s32Ret)
    // {
    //     printf("SVP_NNIE_Init failed!\n");
    //     goto EXIT9;
    // }
    
    // SVP_YOLO_PARAM_S stYoloParam = {0};
    // s32Ret = SVP_NNIE_Yolo_Init(&stNnieParam, &stYoloParam);
    // if (HI_SUCCESS != s32Ret)
    // {
    //     printf("SVP_NNIE_Yolo_Init failed!\n");
    //     goto EXIT10;
    // }

    VIDEO_FRAME_INFO_S stFrmInfo;
    IVE_ROI_INFO_S RoiInfo;
    RoiInfo.u32RoiId = 0;
    RoiInfo.stRoi.s24q8X = 900 * 256;
    RoiInfo.stRoi.s24q8Y = 200 * 256;
    RoiInfo.stRoi.u32Width = 200;
    RoiInfo.stRoi.u32Height = 700;

    s32Ret = IVE_KCFInit();
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] KCF_init error \n");
        goto EXIT11;
    }

    
    HI_S32 UartDev = 1;

    s32Ret = UartInit(UartDev);
    if (HI_SUCCESS != s32Ret)
    {
        printf("[FAIL] UartInit failed!\n");
    } 
    // x y w h
    HI_U32 ac8WriteBuffer[4] = {0,0,200,700};
    int flag = 0;

    while (g_bWorking)
    {
        s32Ret = HI_MPI_VPSS_GetChnFrame(VpssGrp, VpssChn, &stFrmInfo, -1);
        if (HI_SUCCESS != s32Ret)
        {
            printf("[FAIL] HI_MPI_VPSS_GetChnFrame: %x\n", s32Ret);
            continue;
        }


        s32Ret = SAMPLE_IVE_KcfTracking(&stFrmInfo,&RoiInfo,0,&ac8WriteBuffer);
        if(HI_SUCCESS != s32Ret)
        {
            printf("[FAIL] SAMPLE_IVE_KcfTracking failed: %d\n", s32Ret);
        }

        s32Ret = UartSend(UartDev, ac8WriteBuffer, sizeof(ac8WriteBuffer), HI_TRUE);
        if (HI_SUCCESS != s32Ret)
        {
            printf("[FAIL] UartSend failed!\n");
        }
             
        // if(ac8WriteBuffer[0]<1600 && flag == 0)
        // {
        //    ac8WriteBuffer[0] += 50; 
        // }
        // else if (flag == 0)
        // {
        // flag = 1
        // }
        //else if (flag == 1 && ac8WriteBuffer[0]>400)
        // {
        //    ac8WriteBuffer[0] -= 50;
        //   
        // }
        // else if (flag == 1)
        // {
        //       flag = 0;
        // }
        // printf("ac8WriteBuffer is %d\n", ac8WriteBuffer[0]);
        // usleep(20000);

        s32Ret = HI_MPI_VO_SendFrame(VoLayer, VoChn, &stFrmInfo, -1);
        if (HI_SUCCESS != s32Ret)
        {
            printf("[FAIL] HI_MPI_VO_SendFrame: %x\n", s32Ret);
        }

        s32Ret = HI_MPI_VPSS_ReleaseChnFrame(VpssGrp, VpssChn, &stFrmInfo);
        if (HI_SUCCESS != s32Ret)
        {
            printf("[FAIL] HI_MPI_VPSS_ReleaseChnFrame: %x\n", s32Ret);
        }
    }
EXIT11:
    IVE_KCFDeInit();
// EXIT10:
//     SVP_NNIE_Yolo_DeInit(&stYoloParam);
// EXIT9:
//     SVP_NNIE_DeInit(&stNnieParam);
EXIT8:
    VO_DeInit(VoDev, VoLayer, VoChn);
EXIT7:
    LCD_MIPI_DeInit();
EXIT6:
    VI_UnBind_VPSS(ViPipe, ViChn, VpssGrp, VpssChn);
EXIT5:
    VPSS_DeInit(VpssGrp, VpssChn);
EXIT4:
    ISP_DeInit(ViPipe);
EXIT3:
    VI_DeInit(ViDev, ViPipe, ViChn);
EXIT2:
    SNS_MIPI_DeInit(MipiDev);
EXIT1:
    SYS_DeInit();

    return s32Ret;
}